﻿ #region Disclaimer/Info
 
 /////////////////////////////////////////////////////////////////////////////////////////////////
 //
 //   File:		StreamExtensions.cs
 //   Website:		http://dexterblogengine.com/
 //   Authors:		http://dexterblogengine.com/About.ashx
 //   Rev:		1
 //   Created:		19/01/2011
 //   Last edit:		19/01/2011
 //   License:		GNU Library General Public License (LGPL)
 //   File:            StreamExtensions.cs
 //   For updated news and information please visit http://dexterblogengine.com/
 //   Dexter is hosted to Codeplex at http://dexterblogengine.codeplex.com
 //   For any question contact info@dexterblogengine.com
 //
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
 #endregion
 
namespace System.IO
{
	#region Usings

	using System.Security.Cryptography;

	#endregion

	/// <summary>
	/// 	Extends the System.IO classes
	/// </summary>
	public static class StreamExtensions
	{
		/// <summary>
		/// 	Asyncs the copy to stream.
		/// </summary>
		/// <param name = "source">The source.</param>
		/// <param name = "destination">The destination.</param>
		/// <param name = "completed">The completed.</param>
		public static void AsyncCopyToStream ( this Stream source , Stream destination , Action<Exception> completed )
		{
			byte[] buffer = new byte[0x1000];
			if ( completed == null )
				completed = delegate { };

			AsyncCallback rc = null;
			rc = readResult =>
			     	{
			     		try
			     		{
			     			int read = source.EndRead ( readResult );
			     			if ( read > 0 )
			     			{
			     				destination.BeginWrite ( buffer , 0 , read , writeResult =>
			     				                                             	{
			     				                                             		try
			     				                                             		{
			     				                                             			destination.EndWrite ( writeResult );
			     				                                             			source.BeginRead (
			     				                                             				buffer , 0 , buffer.Length , rc , null );
			     				                                             		}
			     				                                             		catch ( Exception exc )
			     				                                             		{
			     				                                             			completed ( exc );
			     				                                             		}
			     				                                             	} , null );
			     			}
			     			else
			     				completed ( null );
			     		}
			     		catch ( Exception exc )
			     		{
			     			completed ( exc );
			     		}
			     	};

			source.BeginRead ( buffer , 0 , buffer.Length , rc , null );
		}

		/// <summary>
		/// 	Gets all bytes.
		/// </summary>
		/// <param name = "source">The source.</param>
		/// <returns></returns>
		public static byte[] GetAllBytes ( this Stream source ) {
			source.Position = 0;
			BinaryReader b = new BinaryReader ( source );
			return b.ReadBytes ( ( int ) source.Length );
		}

		/// <summary>
		/// 	Copies to stream.
		/// </summary>
		/// <param name = "source">The source.</param>
		/// <param name = "target">The target.</param>
		/// <param name = "bufferSize">Size of the buffer.</param>
		public static void CopyToStream ( this Stream source , Stream target , int bufferSize )
		{
			int i;

			byte[] buffer = new byte[bufferSize];

			while ( ( i = source.Read ( buffer , 0 , bufferSize ) ) > 0 )
				target.Write ( buffer , 0 , i );
		}

		/// <summary>
		/// 	Gets the M d5 hash.
		/// </summary>
		/// <param name = "source">The source.</param>
		/// <returns></returns>
		public static string GetMd5Hash ( this Stream source )
		{
			MD5 md5 = MD5.Create ();

			byte[] bytes = md5.ComputeHash ( source );

			return Convert.ToBase64String ( bytes );
		}
	}
}
